package com.lwlk.util.biginteger;


import java.math.BigInteger;
import java.util.Arrays;
import java.util.stream.Stream;


public class Nifix {

    private static class NifixOperator { }

    private static final class NifixAdd extends NifixOperator { }

    private static final NifixAdd Add = new NifixAdd();

    // 计算工具
    private static BigInteger $(NifixAdd op, BigInteger ... ints) {
        return Stream.of(ints).reduce(BigInteger::add).get();
    }

    // 类型转换工具
    private static BigInteger[] $(String ... args) {
        return Arrays.stream(args)
                .parallel()
                .map(BigInteger::new)
                .toArray(BigInteger[]::new);
    }

    private static BigInteger[] $(int ... args) {
        return Arrays.stream(args)
                .parallel()
                .mapToObj(String::valueOf)
                .map(BigInteger::new)
                .toArray(BigInteger[]::new);
    }

    private static BigInteger[] $(long ... args) {
        return Arrays.stream(args)
                .parallel()
                .mapToObj(String::valueOf)
                .map(BigInteger::new)
                .toArray(BigInteger[]::new);
    }

    private static BigInteger[] $(BigInteger[] ... args) {
        return Arrays.stream(args)
                .parallel()
                .map(Arrays::asList)
                .reduce((c, i) -> c.addAll(i) ? c : c)
                .get()
                .toArray(new BigInteger[0]);
    }

    public static void main(String[] args) {

        // a.add(b.add(c)) => $(Add, $(a, b, c))

        System.out.println($(Add, $(
                "11111111111111111111111111111111111111111",
                "11111111111111111111111111111111111111111",
                "11111111111111111111111111111111111111111",
                "11111111111111111111111111111111111111111"
        )));
    }
}
